import { ref, Ref } from 'vue'

/**
 * 生成提交表单处理函数的工具函数
 *
 * @param {() => Promise<boolean>} beforeSubmit 在提交表单之前执行的函数，返回 true 表
 * 示继续提交表单，返回 false 表示取消提交表单
 * @param {() => Promise<void>} handleSubmit 处理表单的提交
 * @param {(res: any) => Promise<any>} afterSubmit 在提交表单之后执行的函数，该函数接收
 * 处理表单提交的返回值作为参数
 * @param {(err: any) => void} error 出错时的处理函数，该函数接收出错信息作为参数
 * @param {(handler: () => Promise<void>) => () => Promise<void>} handleHandler 对生成的处理函数进行额外的处理，该函数接收生成的
 * 处理函数作为参数，需要处理过后的处理函数
 * @returns {[Ref<boolean>, () => Promise<void>]} 返回一个数组，包含以下两个元素：
 * - 1. 表单是否正在提交的响应式状态
 * - 2. 提交表单的处理函数
 */
export const genSubmitFormHandler = ({
  beforeSubmit = async () => true,
  handleSubmit,
  afterSubmit = async () => {},
  error = () => {},
  handleHandler = handler => handler
}: {
  beforeSubmit?: () => Promise<boolean>
  handleSubmit: () => Promise<any>
  afterSubmit?: (res: any) => Promise<void>
  error?: (err: any) => void
  handleHandler?: (handler: () => Promise<void>) => () => Promise<void>
}): [Ref<boolean>, () => Promise<void>] => {
  const isSubmitting = ref<boolean>(false)
  const handler = async () => {
    isSubmitting.value = true
    try {
      if (!(await beforeSubmit())) {
        isSubmitting.value = false
        return
      }
      const res = await handleSubmit()
      await afterSubmit(res)
    } catch (err) {
      error(err)
    } finally {
      isSubmitting.value = false
    }
  }

  return [isSubmitting, handleHandler(handler)]
}

export type GenSubmitFormHandlerType = typeof genSubmitFormHandler
